package mbsl.main;

/**
 * A status bar controller.
 * <p>
 * This class is a framework and an interface for status bar controllers. Not
 * all implementations need to use all the functionality, as not all status bars
 * have a status field ("Ready", "Busy", and the likes), nor have any use for an
 * ownership system. It is recommended to simply have these methods do nothing,
 * thus ensuring that the convenience methods provided by this class still work.
 */
public abstract class StatusBarController {
	/**
	 * Requests that this StatusBarController owns the status bar until
	 * released.
	 * 
	 * @return true if successful and false otherwise.
	 */
	public boolean requestOwnership() {
		return requestOwnership(false);
	}
	/**
	 * Requests that this StatusBarController owns the status bar until
	 * released.

	 * @param force
	 *            Whether to force the change.
	 * @return true if successful and false otherwise.
	 */
	public abstract boolean requestOwnership(boolean force);
	/**
	 * Requests that this StatusBarController owns the status bar until
	 * released.
	 * <p>
	 * If the controller passed is the one currently owning the status bar, the
	 * request will be accepted. When this controller calls release(), control
	 * will be returned to the parent controller.
	 * 
	 * @param parent 
	 * @return
	 */
	public abstract boolean requestOwnership(StatusBarController parent);
	/**
	 * Releases the status bar if this StatusBarController is its current owner.
	 * Does nothing otherwise.
	 */
	public abstract void release();
	/**
	 * Attempts to set the status field of the status bar to <i>status</i>.
	 * <p>
	 * This method will do nothing if the status bar is owned by another
	 * StatusBarController.
	 * 
	 * @param status
	 *            The value to set the status field to.
	 */
	public abstract void setStatus(Status status);
	/**
	 * Attempts to set the info message on the status bar to <i>message</i>.
	 * <p>
	 * This method will do nothing if the status bar is owned by another
	 * StatusBarController.
	 * 
	 * @param message
	 *            The message to put on the status bar.
	 */
	public abstract void setInfo(String message);
	/**
	 * Attempts to set the progress bar to <i>percentage</i>%.
	 * <p>
	 * If a value outside the range [0, 100] is passed, it will be set to the
	 * closest valid value.
	 * <p>
	 * This method will do nothing if the status bar is owned by another
	 * StatusBarController.
	 * 
	 * @param percentage
	 *            The percentage to set the progress bar to.
	 */
	public abstract void setProgress(int percentage);
	/**
	 * Convenience method for setProgress(100 * (<i>current</i> /
	 * <i>total</i>)).
	 * <p>
	 * This method will do nothing if the status bar is owned by another
	 * StatusBarController.
	 * 
	 * @param total
	 *            The total number of steps.
	 * @param current
	 *            The number of the current step.
	 */
	public void setProgress(int current, int total) {
		setProgress((int)(100 * ((double)current / total)));
	}
	/**
	 * Convenience method for setInfo(String.format(message, Object ...
	 * objects)).
	 * <p>
	 * This method will do nothing if the status bar is owned by another
	 * StatusBarController.
	 * 
	 * @param message
	 *            The message to be formatted and put on the status bar.
	 * @param objects
	 *            The objects used to format this message.
	 */
	public void setInfo(String message, Object... objects) {
		if (message == null)
			setInfo(null);
		else
			setInfo(String.format(message, objects));
	}
	/**
	 * Convenience method for setProgress(100).
	 * <p>
	 * This method will do nothing if the status bar is owned by another
	 * StatusBarController.
	 */
	public void setFinished() {
		setProgress(100);
	}
	/**
	 * Convenience method for posting the passed message, setting the status to
	 * ready, clearing the progress bar, and releasing control of the info bar.
	 * <p>
	 * This method will do nothing if the status bar is owned by another
	 * StatusBarController.
	 * 
	 * @param message
	 *            The message to be formatted and put on the status bar.
	 * @param objects
	 *            The objects used to format this message.
	 */
	public void finishAndRelease(String message, Object... objects) {
		setInfo(message, objects);
		setStatus(Status.Ready);
		setFinished();
		release();
	}

	public enum Status {
		Ready, Working, Error;
	}
}
